package com.rw.coco.handler.message.reply.handler.command.assistant;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 正则表达式匹配类
 */
public class CommandMatcher {
    private final List<String> commandList;
    private final List<Pattern> patternList;

    public CommandMatcher(List<String> commandList) {
        this.commandList = commandList;
        this.patternList = commandList.stream()
                .map(command -> Pattern.compile("^" + command + ".*", Pattern.CASE_INSENSITIVE))
                .collect(Collectors.toList());
    }

    public static CommandMatcher of(String... commandList) {
        return new CommandMatcher(Arrays.asList(commandList));
    }

    public Optional<String> match(String msg) {
        for (int i = 0; i < patternList.size(); i++) {
            Pattern pattern = patternList.get(i);
            if (pattern.matcher(msg).find()) {
                return Optional.of(commandList.get(i));
            }
        }
        return Optional.empty();
    }

    public String assertMatch(String msg) {
        return match(msg).orElseThrow(() -> new IllegalArgumentException("没有找到可以与msg匹配的正则表达式！"));
    }

    public boolean isMatch(String msg) {
        return match(msg).isPresent();
    }

    public boolean isMatch(String msg, int index) {
        return patternList.get(index).matcher(msg).find();
    }

    public String sub(String msg) {
        for (int i = 0; i < patternList.size(); i++) {
            Pattern pattern = patternList.get(i);
            if (pattern.matcher(msg).find()) {
                return msg.substring(commandList.get(i).length());
            }
        }

        throw new IllegalArgumentException("没有找到可以与msg匹配的正则表达式！");
    }

    public String subTrim(String msg) {
        return sub(msg).trim();
    }

    public String subBlank(String msg) {
        return sub(msg).replaceAll("[\\s\\n]", "");
    }

    public int priority() {
        return commandList.stream().map(String::length).min(Integer::compareTo).orElse(0);
    }
}
